package com.example.merchantdemo.util;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class SignatureGenerateHelper {

    private static final Logger log = LoggerFactory.getLogger(SignatureGenerateHelper.class);

    /**
     * 验证签名需要跳过的字段列表
     */
    public static final List<String> signIgnoreFiledList = Arrays.asList("merchantSign");

    /**
     * 验证 RSA 签名
     *
     * @param publicKey
     * @param jsonStr
     * @param rawSign
     * @return
     */
    public static boolean verifyRSASign(String publicKey, String jsonStr, String rawSign) {
        String clearTextSign = generateClearTextSign(jsonStr);
        log.info("明文签名为:"+clearTextSign);
        // 验证签名
        return RSAUtils.verifySign(publicKey, clearTextSign, rawSign);
    }

    /**
     * 根据json串生成明文签名
     *
     * @param jsonStr
     * @return
     */
    public static String generateClearTextSign(String jsonStr) {
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        Map<String, Object> treeMap = new TreeMap<>();

        // 将value不为null的放进treeMap
        for (String key : jsonObject.keySet()) {
            if (jsonObject.get(key) != null && !signIgnoreFiledList.contains(key)) {
                treeMap.put(key, jsonObject.get(key));
            }
        }

        StringBuffer sb = new StringBuffer();
        for (String key : treeMap.keySet()) {
            // 字母序降序排列拼接
            if (!(treeMap.get(key) instanceof List)) {
                sb.append(key + "=" + treeMap.get(key) + ",");
            }
        }
        log.info("生成商家签名明文：{}", sb.toString().substring(0, sb.length() - 1));
        return sb.toString().substring(0, sb.length() - 1);
    }

    /**
     * 生成签名
     *
     * @param privateKey 商家私钥
     * @param resp       返回参数object
     * @return
     */
    public static String generateSign(String privateKey, Object resp) {
        String sign = RSAUtils.sign(privateKey,
                generateClearTextSign(JSONObject.toJSONString(resp)));
        return sign;
    }


}
